/*
 * Aho-Corasick automaton
 */

#include <string.h>
#include <queue>
#include <map>
#include <iostream>
#include <stdio.h>

using namespace std;

const int INTMAX = 1 << 30;
const int MAX = 1005;
const int N = 1005;

int top; // Used to build the trie tree.

int dp[N][MAX];

map<char, int> mp;

class ACNode
{
public:
	bool final;	// If it is a final status.

	/*
	 * The default fail node points to root, whose location is
	 * trie[0].
	 */
	int fail;	// Fail node.

	/*
	 * If there are no children, then all the four elements' value
	 * are set to zero.
	 */
	int child[4];	// At most four children: A, C, T, G.

	void init()
	{
		final = false;
		fail = -1;
		memset(child, 0, sizeof(child));
	}
};

// root = trie[0];
ACNode trie[MAX];

void init()
{
	// The root node has already occupied the first place.
	top = 1;
	trie[0].init();
}

// Build the trie tree.
void insert(char *str, int len)
{
	// root = trie[0]
	int now = 0;

	for(int i = 0;i<len;i++)
	{
		if(trie[now].child[mp[str[i]]] == 0)
		{
			trie[now].child[mp[str[i]]] = top++;
			trie[top - 1].init();
		}

		now = trie[now].child[mp[str[i]]];

		if(trie[now].final == true)
			break;
	}

	trie[now].final = true;
}

void buildACAtom()
{
	queue<int> q;

	q.push(0);

	int now;

	while(!q.empty())
	{
		now = q.front();
		q.pop();

		// For each of the four children.
		for(int i = 0;i<4;i++)
		{
			if(trie[now].child[i])
			{
				q.push(trie[now].child[i]);
				int temp = trie[now].fail;

				while(temp != -1)
				{
					if(trie[temp].child[i] != 0)
					{
						trie[trie[now].child[i]].fail = trie[temp].child[i];

						if(trie[trie[temp].child[i]].final)
							trie[trie[now].child[i]].final = true;

						break;
					}
					temp = trie[temp].fail;
				}

				if(temp < 0)
				{
					trie[trie[now].child[i]].fail = 0;
				}
			}
			else
			{
				int temp = trie[now].fail;

				while(temp != -1 && trie[temp].child[i] == 0)
				{
					temp = trie[temp].fail;
				}

				if(temp < 0)
				{
					trie[now].child[i] = 0;
				}
				else
				{
					trie[now].child[i] = trie[temp].child[i];
				}
			}
		}
	}
}

char buf[1005];

int solve(int n)
{
	init();

	for(int i = 0;i<n;i++)
	{
		scanf("%s", buf);

		insert(buf, strlen(buf));
	}

	buildACAtom();

	// TODO: Finish the dynamic programming.
	scanf("%s", buf);

	int len = strlen(buf);

	for(int i = 0;i<len + 1;i++)
	{
		for(int j = 0;j<top;j++)
		{
			dp[i][j] = INTMAX;
		}
	}

	int temp;
	dp[0][0] = 0;
	for(int i = 0;i<len;i++)
	{
		temp = mp[buf[i]];
		for(int j = 0;j<top;j++)
		{
			if(dp[i][j] > len || trie[j].final)
			{
				continue;
			}

			for(int k = 0;k<4;k++)
			{

				if(trie[trie[j].child[k]].final)
				{
					// Reaching this point means a failure.
					continue;
				}

				int status = trie[j].child[k];

				dp[i+1][status] = min(dp[i+1][status], dp[i][j] + (k != temp));
			}
		}
	}

	int res = INTMAX;
	for(int i = 0;i<top;i++)
	{
		if(trie[i].final == false)
			res = min(res, dp[len][i]);
	}

	return res > len ? -1 : res;
}

int main()
{
	int n;

	int cas = 0;

	mp['A'] = 0;
	mp['C'] = 1;
	mp['G'] = 2;
	mp['T'] = 3;

	while(scanf("%d", &n) != EOF)
	{
		if(n == 0)
		{
			break;
		}

		int res = solve(n);

		printf("Case %d: %d\n", ++ cas, res);
	}
}